package com.spark.market.common.interceptor;

import com.spark.market.api.utils.ResponseResult;
import com.spark.market.api.utils.ResponseUtil;
import com.spark.market.common.constants.LogFileName;
import com.spark.market.common.exception.AssertException;
import com.spark.market.common.exception.BusinessException;
import com.spark.market.common.exception.EmBusinessError;
import com.spark.market.common.utils.LoggerUtils;
import org.slf4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import org.springframework.web.servlet.NoHandlerFoundException;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;

@ControllerAdvice(
        //指定拦截包的控制器
        basePackages = {"com.spark.market.controller.*", "com.spark.market.common.interceptor.*"},
        //限定被标注为@Controller,@RestController的类才拦截
        annotations = {Controller.class, RestController.class}
    )
public class ControllerExceptionAdvice {
    Logger LOGGER = LoggerUtils.Logger(LogFileName.MARKET_ERROR_LOG);
    @ExceptionHandler(value = BusinessException.class)
    @ResponseBody
    public ResponseResult<Object> exception(BusinessException ex){
        Map<String,Object> responseData = new HashMap<>();
        responseData.put("errCode",ex.getErrCode());
        responseData.put("errMsg",ex.getErrMsg());
        StringWriter sw = new StringWriter();
        ex.printStackTrace(new PrintWriter(sw));
        LOGGER.error("ERROR:" + sw);
        return ResponseUtil.createFailedResult(responseData, "fail");
    }

    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public ResponseResult<Object> defaultException(Exception ex){
        Map<String,Object> responseData = new HashMap<>();
        responseData.put("errCode",EmBusinessError.UNKNOWN_ERROR.getErrCode());
        responseData.put("errMsg",EmBusinessError.UNKNOWN_ERROR.getErrMsg());
        StringWriter sw = new StringWriter();
        ex.printStackTrace(new PrintWriter(sw));
        LOGGER.error("ERROR:" + sw);
        return ResponseUtil.createFailedResult(responseData, "fail");
    }

    @ExceptionHandler(value = ServletRequestBindingException.class)
    @ResponseBody
    public ResponseResult<Object> urlBindException(ServletRequestBindingException ex){
        Map<String,Object> responseData = new HashMap<>();
        responseData.put("errCode",EmBusinessError.UNKNOWN_ERROR.getErrCode());
        responseData.put("errMsg","url绑定路由问题");
        StringWriter sw = new StringWriter();
        ex.printStackTrace(new PrintWriter(sw));
        LOGGER.error("ERROR:" + sw);
        return ResponseUtil.createFailedResult(responseData, "fail");
    }

    @ExceptionHandler(value = NoHandlerFoundException.class)
    @ResponseBody
    public ResponseResult<Object> handlerFoundException(NoHandlerFoundException ex){
        Map<String,Object> responseData = new HashMap<>();
        responseData.put("errCode",EmBusinessError.UNKNOWN_ERROR.getErrCode());
        responseData.put("errMsg","没有找到对应的访问路径");
        StringWriter sw = new StringWriter();
        ex.printStackTrace(new PrintWriter(sw));
        LOGGER.error("ERROR:" + sw);
        return ResponseUtil.createFailedResult(responseData, "fail");
    }

    @ExceptionHandler(value = AssertException.class)
    @ResponseBody
    public ResponseResult<Object> assertException(AssertException ex){
        Map<String,Object> responseData = new HashMap<>();
        responseData.put("errCode",ex.getErrCode());
        responseData.put("errMsg",ex.getErrMsg());
        StringWriter sw = new StringWriter();
        ex.printStackTrace(new PrintWriter(sw));
        LOGGER.error("ERROR:" + sw);
        return ResponseUtil.createFailedResult(responseData, "fail");
    }

    @ExceptionHandler(value = MethodArgumentTypeMismatchException.class)
    @ResponseBody
    public ResponseResult<Object> MethodArgsException(MethodArgumentTypeMismatchException ex){
        Map<String,Object> responseData = new HashMap<>();
        responseData.put("errCode",EmBusinessError.UNKNOWN_ERROR.getErrCode());
        responseData.put("errMsg","参数类型错误，请核对参数类型");
        StringWriter sw = new StringWriter();
        ex.printStackTrace(new PrintWriter(sw));
        LOGGER.error("ERROR:" + sw);
        return ResponseUtil.createFailedResult(responseData, "fail");
    }
}
